﻿using System.IO.Pipes;
using System.IO;
using System.Threading.Tasks;
using System;

namespace Yt.Core.IPC.NamedPipe
{
    /// <summary>
    /// 命名管道客户端
    /// </summary>
    internal class PipeClientBuilder : PipeBuilderBase
    {
        protected PipeClientBuilder(string pipeName) : base(pipeName)
        {
            pipeStream = CreateNamedPipeClient(pipeName);
        }
        /// <summary>
        /// 创建命名管道客户端实例
        /// </summary>
        /// <param name="pipeName">管道名称</param>
        /// <returns></returns>
        internal static PipeBuilderBase CreateBuilder(string pipeName)
        {
            return new PipeClientBuilder(pipeName);

        }
        private NamedPipeClientStream CreateNamedPipeClient(string pipeName)
        {
            pipeStream = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous, System.Security.Principal.TokenImpersonationLevel.None);
            Task.Run(() =>
            {
                try
                {
                    ((NamedPipeClientStream)pipeStream).ConnectAsync().Wait();
                }
                catch (Exception ex)
                {
                    var exception = ex;
                    while (exception.InnerException != null)
                    {
                        exception = ex.InnerException;
                    }

                  
                    OnDisconnect?.BeginInvoke(null, null);
                    return;
                }

                ((NamedPipeClientStream)pipeStream).ReadMode = PipeTransmissionMode.Message;
                streamWriter = new StreamWriter(pipeStream);
                streamReader = new StreamReader(pipeStream);
                OnConnection?.BeginInvoke(null, null);
                Task.Run(() =>
                {
                    while (true)
                    {
                        if (!pipeStream.IsConnected)
                        {
                            OnDisconnect?.BeginInvoke(null, null);
                            break;
                        }
                        System.Threading.Thread.Sleep(10);
                        System.Windows.Forms.Application.DoEvents();
                    }
                });

                DoReadLine();
            });
            return (NamedPipeClientStream)pipeStream;
        }
        ~PipeClientBuilder()
        {
            Dispose();
        }
    }
}
